线上问题,事务互锁,不能操作数据库
上线一个支付功能,由于用户量过大,需要频繁的获取未支付订单的所有状态
结果频繁报错
1 | Caused by: com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 20, maxActive 20, creating 0, runningSqlCount 8 : SELECT id,pay_code,yaoma,manager,manager_id,paid_cash_all,pay_name,pay_tel,pay_id,pay_bh,pay_datetime,pay_method,manually_add_user,manually_add_user_id,manually_add_datetime,pay_state,openid,le_shua_pay_state,paychanel_order_id,sign_type,out_trade_no,create_time,create_user,update_time,update_user FROM my_payment_order |
一开始以为是数据库链接池不对,增大了链接池,结果不生效
后来查到原因是查询支付接口订单的时候只能单个订单查询,调用外部支付接口的支付订单信息
注意,此处开启了事务,但是订单很多,循环调用很多次外部接口,查询订单信息,若同时并发此处会造成事务死锁
1 | /** |
更新前的单数据更新sql
1 | <update id="updateMyPaymentOrder" parameterType="com.halfsky.my.modular.paymentorder.entity.myPaymentOrder" > |
更新后批量数据更新sql
1 | <!-- 批量更新 --> |
总结
单个方法中对多个表的数据修改,编辑,删除数据都要增加事务注解(@Transactional(rollbackFor = Exception.class))
在方法中尽可能的减少对数据库的占用时间,特别是需要调用外部接口之后的修改,建议批量修改,而不是单个修改。
多次的操纵单次修改,在并发量很大的情况下容易造成事务的互锁。
一辈子很短,努力的做好两件事就好;
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;